package com.starry.core.security.context;

import cn.hutool.json.JSONUtil;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.starry.core.security.domain.BaseUser;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;

/**
 * 认证信息上下文
 *
 * @Author xiaoke
 */
public class SecurityInfoContext {

    /**
     * 登录用户信息
     */
    private static final ThreadLocal<BaseUser> LOGIN_USER_DTO = new TransmittableThreadLocal<>();

    /**
     * 获取当前登录用户Jwt
     *
     * @return Jwt
     */
    public static Jwt getCurrentUserJwt() {
        SecurityContext context = SecurityContextHolder.getContext();
        Object principal = context.getAuthentication().getPrincipal();
        if (principal instanceof Jwt) {
            return (Jwt) principal;
        } else if (principal instanceof JwtAuthenticationToken) {
            return ((JwtAuthenticationToken) principal).getToken();
        }
        return null;
    }

    public static BaseUser getLoginUser() {
        if (LOGIN_USER_DTO.get() != null) return LOGIN_USER_DTO.get();
        Jwt jwt = getCurrentUserJwt();
        if (jwt != null) {
            String user = jwt.getClaimAsString("user");
            if (!user.isEmpty()) {
                setLoginUser(user);
                return LOGIN_USER_DTO.get();
            }
        }
        return LOGIN_USER_DTO.get();
    }

    public static void setLoginUser(String loginUserStr) {
        try {
            LOGIN_USER_DTO.set(JSONUtil.toBean(loginUserStr, BaseUser.class));
            LOGIN_USER_DTO.get();
        } catch (Exception ignored) {
        }
    }

    /**
     * 获取当前登录用户ID
     *
     * @return 用户ID
     */
    public static Long getUserId() {
        BaseUser loginUser = getLoginUser();
        return loginUser == null ? null : loginUser.getId();
    }

    /**
     * 获取当前登录用户名
     *
     * @return 用户名
     */
    public static String getUsername() {
        BaseUser loginUser = getLoginUser();
        return loginUser == null ? null : loginUser.getUsername();
    }

    /**
     * 获取当前登录用户租户ID
     *
     * @return 租户ID
     */
    public static Long getTenantId() {
        BaseUser loginUser = getLoginUser();
        return loginUser == null ? null : loginUser.getTenantId();
    }

    /**
     * 获取当前登录用户手机号
     *
     * @return 手机号
     */
    public static String getPhone() {
        BaseUser loginUser = getLoginUser();
        return loginUser == null ? null : loginUser.getPhone();
    }

    public static void clear() {
        LOGIN_USER_DTO.remove();
    }
}
